﻿// Copyright 2012 Jack Bulan (agentgeo)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using GemWorkshop.Formats.Nitro;

namespace GemWorkshop.Trainer
{
    public class TrainerSaver
    {
        private TrainerLoader t;

        public TrainerSaver(TrainerLoader tl)
        {
            t = tl;
        }

        public void Save(int tr)
        {
            MemoryStream dMem = t.TrData.ExtractStream((uint)tr);
            BinaryWriter bw = new BinaryWriter(dMem);

            // Save Pokemon format
            //Console.Clear();
            //Console.WriteLine("Saving trainer...");
            if (t.trainer.UniqueMoves && t.trainer.UniqueItems)
                bw.Write((byte)3);
            else if (t.trainer.UniqueMoves)
                bw.Write((byte)1);
            else
                bw.Write((byte)0);

            bw.Write(t.trainer.Class);
            bw.Seek(1, SeekOrigin.Current); // Unknown
            bw.Write(t.trainer.Pokemon);

            bw.Write(t.trainer.Item1);
            bw.Write(t.trainer.Item2);
            bw.Write(t.trainer.Item3);
            bw.Write(t.trainer.Item4);

            bw.Seek(4, SeekOrigin.Current); // Skip some unknowns
            if (t.trainer.DoubleBattle) bw.Write((byte)2);
            else bw.Write((byte)0);

            // There are more unknowns we ignore.

            bw.Close();
            bw.Dispose();
            dMem.Close();
            dMem.Dispose();

            //NarcWriter nw = new NarcWriter(t.TrData);
            //nw.ReplaceFile((uint)tr, dMem);
            t.TrData.ReplaceFile((uint)tr, dMem);

            MemoryStream pMem = t.TrPoke.ExtractStream((uint)tr);
            bw = new BinaryWriter(pMem);

            //Console.WriteLine("Saving pokemon...");
            if (t.trainer.UniqueMoves && t.trainer.UniqueItems)
            {
                for (int i = 0; i < t.trainer.Pokemon; i++)
                {
                    //Console.WriteLine("> Pokemon {0}...", i);
                    bw.Seek(2, SeekOrigin.Current); // ???
                    bw.Write(t.pokemon[i].Level);
                    bw.Write(t.pokemon[i].Species);
                    bw.Write(t.pokemon[i].Attack1);
                    bw.Write(t.pokemon[i].Attack2);
                    bw.Write(t.pokemon[i].Attack3);
                    bw.Write(t.pokemon[i].Attack4);
                    // Assuming that we'll never see a trainer without items...
                    bw.Write(t.pokemon[i].Item);
                }
            }
            else if (t.trainer.UniqueMoves)
            {
                for (int i = 0; i < t.trainer.Pokemon; i++)
                {
                    //Console.WriteLine("> Pokemon {0}...", i);
                    bw.Seek(2, SeekOrigin.Current);
                    bw.Write(t.pokemon[i].Level);
                    bw.Write(t.pokemon[i].Species);
                    bw.Write(t.pokemon[i].Attack1);
                    bw.Write(t.pokemon[i].Attack2);
                    bw.Write(t.pokemon[i].Attack3);
                    bw.Write(t.pokemon[i].Attack4);
                    // No items here!
                }
            }
            else // Normal format...
            {
                if (t.trainer.Pokemon == 1)
                {
                    //Console.WriteLine("> Pokemon 1...");
                    bw.Seek(2, SeekOrigin.Current);
                    bw.Write(t.pokemon[0].Level);
                    bw.Write(t.pokemon[0].Species);
                    bw.Write((ushort)0); // We need it even.
                }
                else
                {
                    for (int i = 0; i < t.trainer.Pokemon; i++)
                    {
                        //Console.WriteLine("> Pokemon {0}...", i);
                        bw.Seek(2, SeekOrigin.Current);
                        //Console.WriteLine(">> Level {0}", t.pokemon[i].Level);
                        bw.Write(t.pokemon[i].Level);
                        //Console.WriteLine(">> Species {0}", t.pokemon[i].Species);
                        bw.Write(t.pokemon[i].Species);
                    }
                }
            }

            bw.Close();
            bw.Dispose();
            pMem.Close();
            pMem.Dispose();

            //nw = new NarcWriter(t.TrPoke);
            //nw.ReplaceFile((uint)tr, pMem);
            t.TrPoke.ReplaceFile((uint)tr, pMem);
        }
    }
}
